#include <iostream>
#include <string>
#include <vector>
#include <unistd.h>
#include "Thread.hpp"
using namespace ThreadModel;


struct ThreadData
{
    ThreadData(int& ticket, const std::string& name, pthread_mutex_t & mutex)
        :_tickets(ticket), _threadName(name), _totals(0), _mutex(mutex)
    {}
    ~ThreadData()
    {}

    int& _tickets;
    std::string _threadName;
    int _totals;

    pthread_mutex_t & _mutex;
};

int g_ticket = 10000;
const int NUM = 3;

// void buyticket(ThreadData& td)
// {
//     while(true)
//     {
//         if(td._tickets > 0)
//         {
//             usleep(1000);
//             printf("%s : tickets %d\n", td._threadName.c_str(), td._tickets);
//             td._tickets--;
//             td._totals++;
//         }
//         else
//         {
//             break;
//         }
//     }
// }

void buyticket(ThreadData& td)
{
    while(true)
    {
        pthread_mutex_lock(&td._mutex);
        if(td._tickets > 0)
        {
            usleep(1000);
            printf("%s : tickets %d\n", td._threadName.c_str(), td._tickets);
            td._tickets--;
            pthread_mutex_unlock(&td._mutex);

            td._totals++;
        }
        else
        {
            pthread_mutex_unlock(&td._mutex);
            break;
        }
    }
}



int main()
{
    pthread_mutex_t mutex;
    pthread_mutex_init(&mutex, nullptr);
    std::vector<Thread<ThreadData>> threads;
    std::vector<ThreadData*> datas;
    for (int i = 0; i < NUM; i++)
    {
        std::string name = "Thread-" + std::to_string(i + 1);
        ThreadData * td = new ThreadData(g_ticket, name, mutex);
        threads.emplace_back(buyticket, *td, name);
        datas.emplace_back(td);
    }
    // std::cout<< "开始创建多线程" <<  std::endl;
    for (auto& thread : threads)
    {
        thread.Start();
    }

    // std::cout << "main thread wait begin...." << std::endl;
    for (auto& thread : threads)
    {
        thread.Join();
    }
    std::cout << "---------------datas--------------------" << std::endl;
    for (auto& p : datas)
    {
        printf("%s : total tickets %d\n", p->_threadName.c_str(), p->_totals);
        delete p;
    }
    std::cout << "tickets : " << g_ticket << std::endl;
    pthread_mutex_destroy(&mutex);
    return 0;
}